package com.zmn.plat.admin.controller.orderconfig.orderstock.channel;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.plat.common.constant.ChannelConsts;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.model.entity.channel.Channel;
import com.zmn.plat.model.entity.orderconfig.orderstock.CategoryVO;
import com.zmn.plat.model.entity.orderconfig.orderstock.channel.CategoryLinkVO;
import com.zmn.plat.model.entity.orderconfig.orderstock.channel.ChannelConfigClose;
import com.zmn.plat.model.entity.orderconfig.orderstock.channel.ChannelConfigClosePageVO;
import com.zmn.plat.model.entity.orderconfig.orderstock.channel.ChannelConfigCloseQuery;
import com.zmn.plat.model.entity.servcategory.ServAssCategoryQuery;
import com.zmn.plat.model.vo.servcategory.ServAssCategoryVO;

/**
 * 渠道库存配置
 *
 * @author xiangjunming
 * @since 2020年3月17日16:49:40
 */
@Controller
@RequestMapping("/channel/config/")
public class ChannelConfigCloseListController extends ChannelConfigCloseBaseController {

    private Logger logger = LoggerFactory.getLogger(ChannelConfigCloseListController.class);

    /**
     * 描述: 列表
     *
     * @param query
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "list")
    @ReadOnlyConnection
    public ModelAndView list(@ModelAttribute ChannelConfigCloseQuery query) {
        ModelAndView mav = new ModelAndView("orderconfig/orderstock/channel/list");
        Integer channelId = query.getChannelId();
        Channel obj = channelService.findByKey(channelId);
        // query.setCloseDayAfterOrEqCurrDay(true);
        // query.setStatus(GlobalConsts.NO);
        Map<String, List<ChannelConfigClose>> channelConfigCloseMap = channelConfigCloseService.listByQuery(query).stream()
            .collect(Collectors.groupingBy(item -> item.getServCategId() + "-" + item.getCategOneId() + "-" + item.getCategTwoId()));
        List<ServAssCategoryVO> dros = listServAssCategoryByChannelIdAndShowType(channelId, ProductConsts.EC_PRODUCT_TYPE);

        Set<CategoryLinkVO> servCategList = new LinkedHashSet<>();
        Set<CategoryLinkVO> categOneList = new LinkedHashSet<>();
        Set<CategoryLinkVO> categTwoList = new LinkedHashSet<>();
        List<ChannelConfigClosePageVO> items = dros.stream().filter(item -> {
            servCategList.add(new CategoryLinkVO(item.getServCategId(), item.getServCategName(), null));
            categOneList.add(new CategoryLinkVO(item.getCategOneId(), item.getCategOneName(), item.getServCategId()));
            categTwoList.add(new CategoryLinkVO(item.getCategId(), item.getCategName(), item.getCategOneId()));
            return (Objects.isNull(query.getServCategId()) || Objects.equals(query.getServCategId(), item.getServCategId()))
                && (Objects.isNull(query.getCategOneId()) || Objects.equals(query.getCategOneId(), item.getCategOneId()))
                && (Objects.isNull(query.getCategTwoId()) || Objects.equals(query.getCategTwoId(), item.getCategId()));
        }).map(item -> {
            ChannelConfigClosePageVO vo = new ChannelConfigClosePageVO();
            vo.setServCategId(item.getServCategId());
            vo.setCategOneId(item.getCategOneId());
            vo.setCategTwoId(item.getCategId());
            vo.setServCategName(item.getServCategName());
            vo.setCategOneName(item.getCategOneName());
            vo.setCategTwoName(item.getCategName());
            List<ChannelConfigClose> channelConfigCloses =
                channelConfigCloseMap.get(item.getServCategId() + "-" + item.getCategOneId() + "-" + item.getCategId());
            if (channelConfigCloses != null && !channelConfigCloses.isEmpty()) {
                List<Date> closeDays = channelConfigCloses.stream()
                    .filter(day -> day.getStatus() == GlobalConsts.NO && day.getDay().getTime() >= DateUtil.getTodayTimestampMillis())
                    .map(ChannelConfigClose::getDay).collect(Collectors.toList());
                vo.setCloseDays(closeDays);

                Optional<ChannelConfigClose> first =
                    channelConfigCloses.stream().sorted(Comparator.comparing(ChannelConfigClose::getUpdateTime).reversed()).findFirst();
                vo.setUpdater(first.get().getUpdater());
                vo.setUpdateTime(first.get().getUpdateTime());
            }
            return vo;
        }).collect(Collectors.toList());
        Integer mergeSettle = getMergeSettle(channelId);
        obj.setMergeSettle(mergeSettle);
        mav.addObject("items", items);
        mav.addObject("query", query);
        mav.addObject("servCategList", servCategList);
        mav.addObject("categOneList", categOneList);
        mav.addObject("categTwoList", categTwoList);
        mav.addObject("obj", obj);
        mav.addObject("flag", 12);
        mav.addObject("addFlag", query.getAddFlag());
        mav.addObject("stockLimit", Arrays.asList(ChannelConsts.ORDER_STOCK_SPECIAL_CHANNEL).contains(channelId));
        return mav;
    }

    private List<ServAssCategoryVO> listServAssCategoryByChannelIdAndShowType(Integer channelId, Integer showType) {
        ServAssCategoryQuery categoryQuery = new ServAssCategoryQuery();
        categoryQuery.setCategOneStatus(GlobalConsts.YES);
        categoryQuery.setCategTwoStatus(GlobalConsts.YES);
        categoryQuery.setShowType(showType);
        if (ProductConsts.EC_PRODUCT_TYPE.equals(showType)) {
            categoryQuery.setServCategShowStatus(GlobalConsts.YES);
        } else {
            categoryQuery.setServCategStatus(GlobalConsts.YES);
        }
        categoryQuery.setChannelId(channelId);
        List<ServAssCategoryVO> list = servAssCategoryService.listByQuery(categoryQuery);
        return list;
    }

    /**
     * 描述: 批量开启页面
     *
     * @param query
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "batchOpen")
    @ReadOnlyConnection
    public ModelAndView batchOpen(@ModelAttribute ChannelConfigCloseQuery query) {
        ModelAndView mav = new ModelAndView("orderconfig/orderstock/batchOpen");
        Integer channelId = query.getChannelId();
        query.setCloseDayAfterOrEqCurrDay(true);
        query.setStatus(GlobalConsts.NO);
        List<ChannelConfigClose> vos = channelConfigCloseService.listByQuery(query);
        Map<String, ServAssCategoryVO> servAssCategoryDROMap =
            listServAssCategoryByChannelIdAndShowType(channelId, ProductConsts.EC_PRODUCT_TYPE).stream().collect(Collectors
                .toMap(item -> item.getServCategId() + "-" + item.getCategOneId() + "-" + item.getCategId(), item -> item, (p, u) -> p));
        List<ChannelConfigClosePageVO> items = vos.stream().map(item -> {
            ChannelConfigClosePageVO vo = new ChannelConfigClosePageVO();
            vo.setId(item.getId());
            vo.setServCategId(item.getServCategId());
            vo.setCategOneId(item.getCategOneId());
            vo.setCategTwoId(item.getCategTwoId());
            vo.setDay(item.getDay());
            ServAssCategoryVO dro =
                servAssCategoryDROMap.get(item.getServCategId() + "-" + item.getCategOneId() + "-" + item.getCategTwoId());
            if (dro != null) {
                vo.setServCategName(dro.getServCategName());
                vo.setCategOneName(dro.getCategOneName());
                vo.setCategTwoName(dro.getCategName());
            }
            return vo;
        }).sorted(Comparator.comparing(ChannelConfigClose::getDay).reversed()).collect(Collectors.toList());
        mav.addObject("query", query);
        mav.addObject("items", items);
        mav.addObject("flag", "CHANNEL");
        mav.addObject("submitURL", "/channel/config/openDays.action");
        return mav;
    }

    /**
     * 描述: 关闭库存页面
     *
     * @param query
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "close")
    @ReadOnlyConnection
    public ModelAndView close(ChannelConfigCloseQuery query) {
        ModelAndView mav = new ModelAndView("orderconfig/orderstock/dutyDate");
        super.dutyDate(mav);
        query.setStatus(GlobalConsts.NO);
        query.setCloseDayAfterOrEqCurrDay(true);
        List<ChannelConfigClose> closeList = channelConfigCloseService.listByQuery(query);
        List<LocalDate> closeDays = closeList.stream().map(item -> item.getDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
            .collect(Collectors.toList());
        Map<String, Object> data = new HashMap<>();
        data.put("channelId", query.getChannelId());
        data.put("categorys", Lists.newArrayList(new CategoryVO(query.getServCategId(), query.getCategOneId(), query.getCategTwoId())));
        mav.addObject("closeDays", closeDays);
        mav.addObject("data", JSON.toJSONString(data));
        mav.addObject("submitURL", "/channel/config/closeDays.action");
        return mav;
    }

    /**
     * 描述: 关闭库存页面
     *
     * @param channelId
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "batchClose")
    @ReadOnlyConnection
    public ModelAndView batchClose(Integer channelId, String storeageCategKey) {
        ModelAndView mav = new ModelAndView("orderconfig/orderstock/dutyDate");
        super.dutyDate(mav);
        List<ChannelConfigClose> closeList = Collections.EMPTY_LIST;
        List<LocalDate> closeDays = closeList.stream().map(item -> item.getDay().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
            .collect(Collectors.toList());
        Map<String, Object> data = new HashMap<>();
        data.put("channelId", channelId);
        mav.addObject("data", JSON.toJSONString(data));
        mav.addObject("storeageCategKey", storeageCategKey);
        mav.addObject("closeDays", closeDays);
        mav.addObject("submitURL", "/channel/config/closeDays.action");
        return mav;
    }

    /**
     * 描述: 开启库存页面
     *
     * @param query
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "open")
    @ReadOnlyConnection
    public ModelAndView open(ChannelConfigCloseQuery query) {
        ModelAndView mav = new ModelAndView("orderconfig/orderstock/open");
        query.setStatus(GlobalConsts.NO);
        query.setCloseDayAfterOrEqCurrDay(true);
        List<ChannelConfigClose> closeList = channelConfigCloseService.listByQuery(query);
        mav.addObject("closeList", closeList);
        mav.addObject("submitURL", "/channel/config/openDays.action");
        return mav;
    }
}
